package org.luxor.commons.redis.client;

import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;

import java.util.concurrent.TimeUnit;

/**
 * Redis 消息队列
 * <p>
 * 建议使用专门的JMS产品代替，避免产生数据挤压导致生产事故。
 *
 * @author WangFan
 * @author Mr.Yan  @date 2019/10/8
 * @version 1.1 (GitHub文档: https://github.com/whvcse/RedisUtil )
 */
public class RedisQueueClient {

    public static final String QUEUE_PREFIX = "luxor:queue:";
    public static final Integer WAIT_TIMEOUT_SECONDS = 30;

    private StringRedisTemplate redisTemplate;

    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
        Assert.notNull(redisTemplate, "stringRedisTemplate must be specified");
    }

    /**
     * 推送消息（从左侧推入) 到队列中
     *
     * @param queueName 队列名
     * @param value     消息内容
     */
    public Long lpush(String queueName, String value) {
        if (StringUtils.isNotBlank(queueName) || value == null) {
            return 0L;
        }
        return redisTemplate.opsForList().leftPush(QUEUE_PREFIX + queueName, value);
    }

    /**
     * 弹出消息（从右侧弹出，没有内容时最多等待30秒）
     *
     * @param queueName 队列名
     * @return 消息内容
     */
    public String brpop(String queueName) {
        if (StringUtils.isNotBlank(queueName)) {
            return null;
        }
        String jsonText = redisTemplate.opsForList().rightPop(QUEUE_PREFIX + queueName, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
        return jsonText;
    }

    /**
     * 获取Queue中的元素个数
     *
     * @param queueName 队列名
     * @return 元素个数
     */
    public Long llen(String queueName) {
        long size = redisTemplate.opsForList().size(QUEUE_PREFIX + queueName);
        return size;
    }

    /**
     * 清空Queue的所有元素
     *
     * @param queueName 队列名
     */
    public void ltrimAll(String queueName) {
        redisTemplate.opsForList().trim(QUEUE_PREFIX + queueName, 1, 0);
    }

}
